import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _findIndex from "lodash/findIndex";
import _toInteger from "lodash/toInteger";
import _isFunction from "lodash/isFunction";
import _isEmpty from "lodash/isEmpty";
import _map from "lodash/map";
import _join from "lodash/join";
import _inRange from "lodash/inRange";
import _isArray from "lodash/isArray";

var _dec, _class, _class2;

import React from 'react';
import { Form, Row, Col, Spin } from 'antd';
import intl from "../../../utils/intl";
import { EMAIL } from "../../../utils/regExp";
import { getColLayout, getGetValuePropFunc, getGetValueFromEventFunc, getInitialValue, getComponentType, renderDisabledField, getComponentProps } from "./utils";
import { getDisplayValue } from "../utils";
var ComposeFormContext = React.createContext();
var FormItem = Form.Item;
var ComposeForm = (_dec = Form.create({
  fieldNameProp: null
}), _dec(_class = (_class2 = /*#__PURE__*/function (_React$PureComponent) {
  _inherits(ComposeForm, _React$PureComponent);

  var _super = _createSuper(ComposeForm);

  function ComposeForm(props) {
    var _this;

    _classCallCheck(this, ComposeForm);

    _this = _super.call(this, props);
    _this.state = {
      // 存之前的 props 做比较用
      col: 3,
      fields: [],
      organizationId: undefined,
      editable: false,
      disableStyle: 'value',
      fieldLabelWidth: 150,
      context: undefined,
      // 渲染好的元素
      rows: [],
      init: false
    };
    _this.checkUpdate = _this.checkUpdate.bind(_assertThisInitialized(_this));
    _this.getDataSource = _this.getDataSource.bind(_assertThisInitialized(_this));
    _this.getValidateDataSource = _this.getValidateDataSource.bind(_assertThisInitialized(_this));
    var col = props.col,
        fields = props.fields,
        organizationId = props.organizationId,
        editable = props.editable,
        disableStyle = props.disableStyle,
        context = props.context,
        fieldLabelWidth = props.fieldLabelWidth;
    _this.state = {
      col: col,
      fields: fields,
      organizationId: organizationId,
      editable: editable,
      disableStyle: disableStyle,
      context: context,
      fieldLabelWidth: fieldLabelWidth,
      rows: _this.renderRows(),
      init: true
    };
    return _this;
  }

  _createClass(ComposeForm, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var _this$props = this.props,
          onRef = _this$props.onRef,
          onGetValidateDataSourceHook = _this$props.onGetValidateDataSourceHook,
          onGetDataSourceHook = _this$props.onGetDataSourceHook; // 传递 this, 获取表单数据的方法, 校验并获取表单数据的方法 传递出去

      if (_isFunction(onRef)) {
        onRef(this);
      }

      if (_isFunction(onGetValidateDataSourceHook)) {
        onGetValidateDataSourceHook(this.getValidateDataSource);
      }

      if (_isFunction(onGetDataSourceHook)) {
        onGetDataSourceHook(this.getDataSource);
      }
    }
    /**
     * 获取表单数据
     * @returns
     * @memberof ComposeForm
     */

  }, {
    key: "getDataSource",
    value: function getDataSource() {
      var _this$props2 = this.props,
          form = _this$props2.form,
          dataSource = _this$props2.dataSource;
      return _objectSpread(_objectSpread({}, dataSource), form.getFieldsValue());
    }
    /**
     * 校验并获取表单数据
     * @returns
     * @memberof ComposeForm
     */

  }, {
    key: "getValidateDataSource",
    value: function getValidateDataSource() {
      var _this$props3 = this.props,
          form = _this$props3.form,
          dataSource = _this$props3.dataSource,
          tabTitle = _this$props3.tabTitle,
          parentTabTitle = _this$props3.parentTabTitle;
      return new Promise(function (resolve, reject) {
        form.validateFields(function (err, fieldsValue) {
          if (err) {
            reject({
              err: err,
              tabTitle: tabTitle,
              parentTabTitle: parentTabTitle
            }); // eslint-disable-line
          } else {
            resolve(_objectSpread(_objectSpread({}, dataSource), fieldsValue));
          }
        });
      });
    }
    /**
     * 检查属性变动 并调用对应的方法
     */

  }, {
    key: "checkUpdate",
    value: function checkUpdate() {
      var _this$props4 = this.props,
          col = _this$props4.col,
          fields = _this$props4.fields,
          organizationId = _this$props4.organizationId,
          editable = _this$props4.editable,
          disableStyle = _this$props4.disableStyle,
          context = _this$props4.context,
          fieldLabelWidth = _this$props4.fieldLabelWidth,
          form = _this$props4.form;
      var _this$state = this.state,
          prevCol = _this$state.col,
          prevFields = _this$state.fields,
          prevOrganizationId = _this$state.organizationId,
          prevEditable = _this$state.editable,
          prevDisplayStyle = _this$state.disableStyle,
          prevContext = _this$state.context,
          prevFieldLabelWidth = _this$state.fieldLabelWidth,
          init = _this$state.init;

      if (init) {
        if (col !== prevCol || fields !== prevFields || organizationId !== prevOrganizationId || editable !== prevEditable || editable === false && disableStyle !== prevDisplayStyle || context !== prevContext || fieldLabelWidth !== prevFieldLabelWidth) {
          // 之后是不是可以根据不同的属性的影响, 来决定影响不同的属性
          // 需要重新渲染 rows
          this.setState({
            col: col,
            fields: fields,
            organizationId: organizationId,
            editable: editable,
            disableStyle: disableStyle,
            context: context,
            fieldLabelWidth: fieldLabelWidth,
            rows: this.renderRows()
          }); // 如果配置或者 dataSource 改变了需要重置表单

          form.resetFields();
        }
      }
    }
    /**
     * 渲染所有表单行
     */

  }, {
    key: "renderRows",
    value: function renderRows() {
      var _this$props5 = this.props,
          col = _this$props5.col,
          fields = _this$props5.fields; // 存放 生成的 Row

      var rows = []; // 所有的 字段的数组
      // 当前遍历的字段的下标

      var walkerIndex = 0; // 当前遍历的 Row 的 fields

      var rowFields = []; // 已经遍历的 Row 的 fields 的宽度和

      var rowCol = 0; // 当前遍历的 Row 的 field 的下标

      var rowIndex = 0;

      if (_isArray(fields)) {
        for (; walkerIndex < fields.length;) {
          var field = fields[walkerIndex];
          rowFields.push(field);

          if (_inRange(field.colspan, 2, col + 1)) {
            rowCol += field.colspan;
          } else {
            rowCol += 1;
          }

          if (_inRange(field.leftOffset, 1, col)) {
            rowCol += field.leftOffset;
          }

          if (_inRange(field.rightOffset, 1, col)) {
            rowCol += field.rightOffset;
          }

          if (rowCol >= col) {
            if (rowCol > col && rowIndex > 0) {
              // 已经超过一列的宽度了,并且字段多于1个 需要 回退
              walkerIndex--;
              rowFields.pop();
            } // 生成 Row 并放入 rows


            rows.push(this.renderRow({
              rowFields: rowFields
            })); // 重置 遍历的 Row 的状态

            rowIndex = 0;
            rowCol = 0;
            rowFields = [];
          } else {
            // 继续向前遍历
            rowIndex++;
          }

          walkerIndex++;
        }

        if (rowIndex > 0) {
          rows.push(this.renderRow({
            rowFields: rowFields
          }));
        }
      }

      return rows;
    }
    /**
     * 渲染表单行
     * @param {Object[]} rowFields - 一行对应的字段
     */

  }, {
    key: "renderRow",
    value: function renderRow(_ref) {
      var _this2 = this;

      var rowFields = _ref.rowFields;
      var disableStyle = this.props.disableStyle;
      return /*#__PURE__*/React.createElement(Row, {
        type: "flex",
        key: _join(_map(rowFields, function (field) {
          return field.fieldCode;
        }), '-'),
        className: disableStyle === 'value' ? 'row-disabled' : ''
      }, _map(rowFields, function (field) {
        return _this2.renderComposeFormField({
          field: field,
          disableStyle: disableStyle
        });
      }));
    }
    /**
     * 渲染最终的字段
     * @param {Object} field - 字段
     */

  }, {
    key: "renderComposeFormField",
    value: function renderComposeFormField(_ref2) {
      var field = _ref2.field;
      var _this$props6 = this.props,
          disableStyle = _this$props6.disableStyle,
          fieldLabelWidth = _this$props6.fieldLabelWidth,
          col = _this$props6.col,
          editable = _this$props6.editable,
          organizationId = _this$props6.organizationId,
          context = _this$props6.context;
      var formItemProps = {
        labelCol: {
          style: {
            width: fieldLabelWidth,
            minWidth: fieldLabelWidth,
            maxWidth: fieldLabelWidth
          }
        },
        wrapperCol: {
          style: {
            flex: 'auto'
          }
        }
      };
      var colProps = getColLayout(col);
      var fieldColProps = getColLayout(col, field.colspan);
      var leftEmptyCols = [];
      var rightEmptyCols = [];

      if (_inRange(field.leftOffset, 1, col)) {
        for (var i = 0; i < field.leftOffset; i++) {
          leftEmptyCols.push( /*#__PURE__*/React.createElement(Col, Object.assign({}, colProps, {
            key: "".concat(field.fieldCode, "#left-offset-").concat(i)
          })));
        }
      }

      if (_inRange(field.rightOffset, 1, col)) {
        for (var _i = 0; _i < field.rightOffset; _i++) {
          rightEmptyCols.push( /*#__PURE__*/React.createElement(Col, Object.assign({}, colProps, {
            key: "".concat(field.fieldCode, "#right-offset-").concat(_i)
          })));
        }
      }

      var ComponentType = getComponentType(field);
      var componentProps = getComponentProps({
        field: field,
        componentType: field.componentType,
        context: context
      });
      var otherFormItemOptions = {};
      var isViewOnly = false; // 附件是否为只读

      var getValueFromEvent = getGetValueFromEventFunc(field.componentType);
      var getValueProps = getGetValuePropFunc(field);

      if (field.componentType === 'Upload') {
        otherFormItemOptions.valuePropName = 'attachmentUUID';

        if (field.props) {
          var propsIndex = _findIndex(field.props, ['attributeName', 'viewOnly']);

          if (propsIndex >= 0) {
            isViewOnly = field.props[propsIndex].attributeValue;
          }
        }
      }

      if (getValueFromEvent) {
        otherFormItemOptions.getValueFromEvent = getValueFromEvent;
      }

      if (getValueProps) {
        // 不影响存的值, 只影响传递给组件的值
        otherFormItemOptions.getValueProps = getValueProps;
      }

      var composeFormItem = /*#__PURE__*/React.createElement(Col, Object.assign({}, fieldColProps, {
        key: field.fieldCode
      }), /*#__PURE__*/React.createElement(ComposeFormContext.Consumer, null, function (_ref3) {
        var form = _ref3.form,
            dataSource = _ref3.dataSource;
        var otherComponentProps = {}; // 为 lov 和 valueList 准备的属性

        switch (field.componentType) {
          case 'Lov':
          case 'ValueList':
            otherComponentProps.textValue = getDisplayValue(field, dataSource);
            break;

          default:
            break;
        }

        return editable ? /*#__PURE__*/React.createElement(FormItem, Object.assign({
          label: field.fieldDescription
        }, formItemProps, {
          required: field.componentType !== 'Checkbox' && _toInteger(field.requiredFlag) !== 0 && !isViewOnly // 当附件只读时，不必输

        }), (field.fieldCode === 'mail' ? form.getFieldDecorator("mail", _objectSpread(_objectSpread({}, otherFormItemOptions), {}, {
          initialValue: getInitialValue({
            field: field,
            dataSource: dataSource
          }),
          rules: [{
            required: true,
            message: intl.get('cpaas.common.validation.notNull', {
              name: intl.get('cpaas.common.email').d('邮箱')
            })
          }, {
            pattern: EMAIL,
            message: intl.get('cpaas.common.validation.email').d('邮箱格式不正确')
          }, {
            max: 60,
            message: intl.get('cpaas.common.validation.max', {
              max: 60
            })
          }]
        })) : form.getFieldDecorator(field.fieldCode, _objectSpread(_objectSpread({}, otherFormItemOptions), {}, {
          initialValue: getInitialValue({
            field: field,
            dataSource: dataSource
          }),
          rules: [{
            required: _toInteger(field.requiredFlag) !== 0 && !isViewOnly,
            message: intl.get('cpaas.common.validation.notNull', {
              name: field.fieldDescription
            })
          }]
        })))(React.createElement(ComponentType, _objectSpread(_objectSpread({}, componentProps), otherComponentProps) // otherComponentProps 比 componentProps 优先级高
        ))) : /*#__PURE__*/React.createElement(FormItem, Object.assign({
          label: field.fieldDescription
        }, formItemProps), renderDisabledField({
          field: field,
          dataSource: dataSource,
          formItemProps: formItemProps,
          organizationId: organizationId,
          disableStyle: disableStyle,
          componentProps: _objectSpread(_objectSpread({}, componentProps), otherComponentProps)
        }));
      }));

      if (_isEmpty(leftEmptyCols) && _isEmpty(rightEmptyCols)) {
        return composeFormItem;
      }

      return /*#__PURE__*/React.createElement(React.Fragment, {
        key: field.fieldCode
      }, leftEmptyCols, composeFormItem, rightEmptyCols);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props7 = this.props,
          _this$props7$editable = _this$props7.editable,
          editable = _this$props7$editable === void 0 ? false : _this$props7$editable,
          form = _this$props7.form,
          dataSource = _this$props7.dataSource,
          _this$props7$loading = _this$props7.loading,
          loading = _this$props7$loading === void 0 ? false : _this$props7$loading;
      var _this$state$rows = this.state.rows,
          rows = _this$state$rows === void 0 ? [] : _this$state$rows;
      this.checkUpdate();
      return /*#__PURE__*/React.createElement(Spin, {
        spinning: loading
      }, /*#__PURE__*/React.createElement(Form, {
        layout: "inline",
        className: editable ? 'compose-form' : 'compose-form-disabled'
      }, /*#__PURE__*/React.createElement(ComposeFormContext.Provider, {
        value: {
          form: form,
          dataSource: dataSource
        }
      }, rows)));
    }
  }]);

  return ComposeForm;
}(React.PureComponent), _class2.defaultProps = {
  // 默认的属性
  col: 3,
  fields: [],
  dataSource: {},
  organizationId: undefined,
  editable: false,
  disableStyle: 'value',
  fieldLabelWidth: 150,
  context: undefined
}, _class2)) || _class);
export { ComposeForm as default };